import pathlib
import time
import re
import typing
import os
import yaml
import ctypes
import psutil
import subprocess
import uiautomation
import win32gui
import requests
import winsound
import datetime
import rich
from selenium.webdriver.edge.webdriver import WebDriver
from selenium.webdriver.edge.service import Service
from selenium.webdriver.edge.options import Options
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions
from selenium.common.exceptions import *













def print_with_time(*args, **kwargs) -> None:
    """在输出内容前添加当前时间戳，使用rich.print进行格式化输出
    
    功能：在所有输出内容前自动添加当前本地时间，时间格式为YYYY-MM-DD HH:MM:SS
    时间会以蓝色加粗样式显示，其余内容保持rich的默认格式化特性
    
    Args:
        *args: 任意数量的位置参数，将被原样传递给rich.print
        **kwargs: 任意关键字参数，将被原样传递给rich.print
    
    Example:
        >>> print_with_time("系统启动完成")
        [bold blue][2025-08-07 16:45:30][/bold blue] 系统启动完成
        
        >>> print_with_time("操作结果：", "[green]成功[/green]")
        [bold blue][2025-08-07 16:46:10][/bold blue] 操作结果：[green]成功[/green]
    """
    # 获取当前时间并格式化为字符串
    current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    # 拼接时间前缀与输出内容并打印
    rich.print(f"[bold blue][{current_time}][/bold blue]", *args, **kwargs)








def On_InputPage_UploadMain_1b1_Picture_ByPictureNameStr(driver:WebDriver,PictureStr:str,Delay:float=5):
    """批量上传主图 1:1  图片

    Args:
        driver (WebDriver): WebDriver 实例
        wait (WebDriverWait): WebDriverWait 实例
        actions (ActionChains):  ActionChains 实例
        PictureStr (str): 需要上传的图片字符串路径
        Delay (float, optional):  延迟时间. Defaults to 5.
    """
    
    # 1.打开 【选择/上传图片】 的对话框
    try:
    
        # 滚动至点击目标元素
        element_xpath = "//div[@id='struct-mainImagesGroup']//div[contains(@class,'upload-text')]"
        element = WebDriverWait(driver=driver,timeout=10).until(expected_conditions.presence_of_element_located((By.XPATH, element_xpath)))
        driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'});",element)


        # 执行点击操作
        try:
            element.click()
            print_with_time(f"提示 : 元素 {element_xpath} 点击成功!")
        except  (ElementClickInterceptedException,ElementNotInteractableException):
            driver.execute_script("arguments[0].click();",element)
            print_with_time(f"提示 : 元素 {element_xpath} 点击失败!采用 js脚本点击!")
    
    # 验证点击后的界面
        try:
            wait_element_xpath = f"//iframe[@id='mainImagesGroup']"
            WebDriverWait(driver=driver,timeout=10).until(expected_conditions.presence_of_element_located((By.XPATH,wait_element_xpath)))
            print_with_time (f"提示 : 已经等到【选择/上传图片】 对话框的元素!")
        except TimeoutException:
            print_with_time(f"提示 :  没有等到【选择/上传图片】 对话框的元素!")
            return
            
    except TimeoutException:
        print_with_time(f"提示 : 没有找到打开 【选择/上传图片】 对话框的元素!")
        return
    
    # 2.切换到iframe中
    try:
        print_with_time(f"提示 : 正在等待进入 iframe!")
        # 滚动至点击目标元素
        element_xpath = "//iframe[@id='mainImagesGroup']"
        element = WebDriverWait(driver=driver,timeout=10).until(expected_conditions.presence_of_element_located((By.XPATH, element_xpath)))

        # 执行 iframe 切换操作
        try:
            WebDriverWait(driver=driver,timeout=10).until(expected_conditions.frame_to_be_available_and_switch_to_it(locator=(By.XPATH,element_xpath)))
            print_with_time(f"提示 : iframe元素已经切换成功!")
        except TimeoutException:
            print_with_time(f"提示 : 没有等到iframe元素,无法进行 iframe 切换!")
            return
            
    # 验证点击后的界面
        try:
            wait_element_xpath = f"//button/span[text()='本地上传']"
            WebDriverWait(driver=driver,timeout=10).until(expected_conditions.presence_of_element_located((By.XPATH,wait_element_xpath)))
            print_with_time(f"提示 : iframe已经切换成功,已经等待锚点元素!")
        except TimeoutException:
            print_with_time(f"提示 :  iframe已经切换成功,但是没有等待锚点元素!")
            return
            
    except TimeoutException:
        print_with_time(f"提示 : 没有找到  iframe 元素!")
        return

    # 3.打开 【上传图片】 的界面
    try:
    
        # 滚动至点击目标元素
        element_xpath = "//button/span[text()='本地上传']"
        element = WebDriverWait(driver=driver,timeout=10).until(expected_conditions.presence_of_element_located((By.XPATH, element_xpath)))
        driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'});",element)

        # 执行点击操作
        try:
            element.click()
            print_with_time(f"提示 : 元素 {element_xpath} 点击成功!")
        except  (ElementClickInterceptedException,ElementNotInteractableException):
            driver.execute_script("arguments[0].click();",element)
            print_with_time(f"提示 : 元素 {element_xpath} 点击失败!采用 js脚本点击!")
        finally:
            close_edge_open_dialog()
    
    # 验证点击后的界面
        try:
            wait_element_xpath = f"//input[@type='file']"
            WebDriverWait(driver=driver,timeout=10).until(expected_conditions.presence_of_element_located((By.XPATH,wait_element_xpath)))
            print_with_time (f"提示 : 已经等到可以上传图片的元素!")
        except TimeoutException:
            print_with_time (f"提示 :  没有等到可以上传图片的元素!")
            return
            
    except TimeoutException:
        print_with_time(f"提示 : 没有找到打开可以上传图片的元素!")
        return

    # 4.上传图片
    try:
        # 滚动至点击目标元素
        element_xpath = "//input[@type='file']"
        element = WebDriverWait(driver=driver,timeout=10).until(expected_conditions.presence_of_element_located((By.XPATH, element_xpath)))
        driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'});",element)

        # 执行键盘操作
        try:
            element.send_keys(PictureStr)
            wait_element_xpath = "//*[contains(text(),'上传中')]"
            element = WebDriverWait(driver=driver,timeout=10).until(expected_conditions.presence_of_element_located(locator=(By.XPATH,wait_element_xpath)))
            print_with_time(f"提示 : 写入上传操作成功,目前正在上传过程中!")
        except TimeoutException:
            print_with_time(f"提示 : 写入上传操作失败!没有等到正在上传的界面!")

        
        # 验证上传完毕之后的界面
        # try:
        #     wait_element_xpath = f"//button[@id='sucai-tu-upload']"
        #     WebDriverWait(driver=driver,timeout=30).until(expected_conditions.invisibility_of_element(element=driver.find_element(by=By.XPATH,value=wait_element_xpath)))
        #     print_with_time(f"提示 : 检测到上传完毕的界面!")
        # except TimeoutException:
        #     print_with_time(f"提示 : 上传图片文件超时,请进行检测!")
        #     return
        wait_start_time = datetime.datetime.now()
        while wait_start_time + datetime.timedelta(seconds=30) > datetime.datetime.now():
            try:
                driver.find_element(by=By.XPATH,value=f"//*[contains(text(),'个文件上传成功')]")
                print_with_time(f"提示 : 写入上传操作成功,目前已经上完完毕!")
                driver.find_element(by=By.XPATH,value=f"//button/span[text()='完成']").click()
                time.sleep(Delay)
                break
            except NoSuchElementException:
                time.sleep(Delay)


    except TimeoutException:
        print_with_time(f"提示 : 没有找到 {element_xpath} 的元素,无法进行上传图片!")
        return

    # 5.在上传完毕之后,要选择上传的图片
        # 获取所有上传图片的列表
    PictureList = PictureStr.split("\n")
    for index,picture_name in enumerate(PictureList,start=1):
        basename = pathlib.Path(picture_name).absolute().resolve().stem
        suffix = pathlib.Path(picture_name).absolute().resolve().suffix
        ImageSpaceName =  f"{basename}.jpg"
        
        try:
             element = WebDriverWait(driver=driver,timeout=10).until(expected_conditions.presence_of_element_located((By.XPATH,f"//div[contains(@class,'PicList_PicturesShow_main-show') and position() <= {PictureList.__len__()} and .//*[contains(text(),'{basename}')]]//img")))
             driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'});",element)      
             try:
                 element.click()
                 print_with_time(f"提示  : 点击图片 {ImageSpaceName} 成功!")
             except  (ElementClickInterceptedException,ElementNotInteractableException):
                  driver.execute_script("arguments[0].click();",element)
                  print_with_time(f"提示 : 点击图片 {ImageSpaceName} 失败!采用 js脚本点击!")
                  
        except TimeoutException:
            print_with_time(f"提示 : 没有找到第 {index} 张图片,该图片的文件名为 {ImageSpaceName}")
        finally:
            time.sleep(Delay)
            try:
                driver.find_element(by=By.XPATH,value=f"//span[text()='智能裁剪中']")
                time.sleep(Delay)
            except NoSuchElementException:
                pass

    driver.switch_to.default_content()
    time.sleep(Delay)




def On_InputPage_UploadMain_1b1_Picture_ByPictureNameList(driver:WebDriver,picture_name_list:list,Delay:float=5):
    """批量上传主图 1:1 图片

    Args:
        driver (WebDriver): driver 实例
        wait (WebDriverWait): WebDriverWait 实例
        actions (ActionChains): ActionChains 实例
        picture_name (list): 图片名称列表
    """
    
    # 1.将图片列表转换为 Selenium 可以使用的格式
    picture_list_str = ""
    for index, picture_name in enumerate(picture_name_list):
        picture_path = str(pathlib.Path(picture_name).absolute().resolve())
        if index >= 5 : continue
        if index > 0:  # 不是第一个元素时才添加换行符
            picture_list_str += "\n"
        picture_list_str += picture_path
    
    # 2.调用复用接口进行上传主图图片
    On_InputPage_UploadMain_1b1_Picture_ByPictureNameStr(driver=driver,PictureStr=picture_list_str,Delay=Delay)

    



def On_InputPage_UploadMain_1b1_Picture_ByDirectory(driver:WebDriver,picture_directory_path:str,Delay:float=5):
    """批量上传主图 1:1 图片

    Args:
        driver (WebDriver): driver 实例
        wait (WebDriverWait): WebDriverWait 实例
        actions (ActionChains): ActionChains 实例
        picture_name (list): 图片名称列表
    """
    # 1.获取图片列表
    picture_name_list = list()
    for item in pathlib.Path(picture_directory_path).rglob('*'):
        if item.is_file():
            picture_image_path = str(item)
            picture_name_list.append(picture_image_path)
    
    
    # 2.将图片列表转换为 Selenium 可以使用的格式
    picture_list_str = ""
    for index, picture_name in enumerate(picture_name_list):
        picture_path = str(pathlib.Path(picture_name).absolute().resolve())
        if index >= 5 : continue
        if index > 0:  # 不是第一个元素时才添加换行符
            picture_list_str += "\n"
        picture_list_str += picture_path
    
    # 3.调用复用接口进行上传主图图片
    On_InputPage_UploadMain_1b1_Picture_ByPictureNameStr(driver=driver,PictureStr=picture_list_str,Delay=Delay)


def close_edge_open_dialog():
    start_time = datetime.datetime.now()
    while start_time + datetime.timedelta(seconds=10) > datetime.datetime.now():
        try:
            _childrens = list(uiautomation.GetRootControl().WindowControl(RegexName='.*?Microsoft.*?Edge').GetChildren())
            if any("打开" in _child.Name for _child in _childrens):
                _dialog = uiautomation.GetRootControl().WindowControl(RegexName='.*?Microsoft.*?Edge').WindowControl(Name='打开')
                win32gui.PostMessage(_dialog.NativeWindowHandle, 0x0010, 0, 0)
                break
        except:
            pass



def On_InputPage_UploadMain_3b4_Picture_ByPictureNameStr(driver:WebDriver,PictureStr:str,Delay:float=5):
    """批量上传主图 3:4  图片

    Args:
        driver (WebDriver): WebDriver 实例
        wait (WebDriverWait): WebDriverWait 实例
        actions (ActionChains):  ActionChains 实例
        PictureStr (str): 需要上传的图片字符串路径
        Delay (float, optional):  延迟时间. Defaults to 5.
    """
    
    # 1.打开 【选择/上传图片】 的对话框
    try:
    
        # 滚动至点击目标元素
        element_xpath = "//div[@id='sell-field-threeToFourImages']//div[contains(@class,'upload-text')]"
        element = WebDriverWait(driver=driver,timeout=10).until(expected_conditions.presence_of_element_located((By.XPATH, element_xpath)))
        driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'});",element)


        # 执行点击操作
        try:
            element.click()
            print_with_time(f"提示 : 元素 {element_xpath} 点击成功!")
        except  (ElementClickInterceptedException,ElementNotInteractableException):
            driver.execute_script("arguments[0].click();",element)
            print_with_time(f"提示 : 元素 {element_xpath} 点击失败!采用 js脚本点击!")
    
    # 验证点击后的界面
        try:
            wait_element_xpath = f"//iframe[@id='threeToFourImages']"
            WebDriverWait(driver=driver,timeout=10).until(expected_conditions.presence_of_element_located((By.XPATH,wait_element_xpath)))
            print_with_time (f"提示 : 已经等到【选择/上传图片】 对话框的元素!")
        except TimeoutException:
            print_with_time(f"提示 :  没有等到【选择/上传图片】 对话框的元素!")
            return
            
    except TimeoutException:
        print_with_time(f"提示 : 没有找到打开 【选择/上传图片】 对话框的元素!")
        return
    
    # 2.切换到iframe中
    try:
    
        # 滚动至点击目标元素
        element_xpath = "//iframe[@id='threeToFourImages']"
        element = WebDriverWait(driver=driver,timeout=10).until(expected_conditions.presence_of_element_located((By.XPATH, element_xpath)))

        # 执行 iframe 切换操作
        try:
            WebDriverWait(driver=driver,timeout=10).until(expected_conditions.frame_to_be_available_and_switch_to_it(locator=(By.XPATH,element_xpath)))
            print_with_time(f"提示 : iframe元素已经切换成功!")
        except TimeoutException:
            print_with_time(f"提示 : 没有等到iframe元素,无法进行 iframe 切换!")
            return
            
    # 验证点击后的界面
        try:
            wait_element_xpath = f"//button/span[text()='本地上传']"
            WebDriverWait(driver=driver,timeout=10).until(expected_conditions.presence_of_element_located((By.XPATH,wait_element_xpath)))
            print_with_time(f"提示 : iframe已经切换成功,已经等待锚点元素!")
        except TimeoutException:
            print_with_time(f"提示 :  iframe已经切换成功,但是没有等待锚点元素!")
            return
            
    except TimeoutException:
        print_with_time(f"提示 : 没有找到  iframe 元素!")
        return

    # 3.打开 【上传图片】 的界面
    try:
    
        # 滚动至点击目标元素
        element_xpath = "//button/span[text()='本地上传']"
        element = WebDriverWait(driver=driver,timeout=10).until(expected_conditions.presence_of_element_located((By.XPATH, element_xpath)))
        driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'});",element)

        # 执行点击操作
        try:
            element.click()
            print_with_time(f"提示 : 元素 {element_xpath} 点击成功!")
        except  (ElementClickInterceptedException,ElementNotInteractableException):
            driver.execute_script("arguments[0].click();",element)
            print_with_time(f"提示 : 元素 {element_xpath} 点击失败!采用 js脚本点击!")
    
    # 验证点击后的界面
        try:
            wait_element_xpath = f"//input[@type='file']"
            WebDriverWait(driver=driver,timeout=10).until(expected_conditions.presence_of_element_located((By.XPATH,wait_element_xpath)))
            print_with_time (f"提示 : 已经等到可以上传图片的元素!")
        except TimeoutException:
            print_with_time (f"提示 :  没有等到可以上传图片的元素!")
            return
            
    except TimeoutException:
        print_with_time(f"提示 : 没有找到打开可以上传图片的元素!")
        return

    # 4.上传图片
    try:
        # 滚动至点击目标元素
        element_xpath = "//input[@type='file']"
        element = WebDriverWait(driver=driver,timeout=10).until(expected_conditions.presence_of_element_located((By.XPATH, element_xpath)))
        driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'});",element)

        # 执行键盘操作
        try:
            element.send_keys(PictureStr)
            wait_element_xpath = "//*[contains(text(),'上传中')]"
            element = WebDriverWait(driver=driver,timeout=10).until(expected_conditions.presence_of_element_located(locator=(By.XPATH,wait_element_xpath)))
            print_with_time(f"提示 : 写入上传操作成功,目前正在上传过程中!")
        except TimeoutException:
            print_with_time(f"提示 : 写入上传操作失败!没有等到正在上传的界面!")

        
        # 验证上传完毕之后的界面
        # try:
        #     wait_element_xpath = f"//button[@id='sucai-tu-upload']"
        #     WebDriverWait(driver=driver,timeout=30).until(expected_conditions.invisibility_of_element(element=driver.find_element(by=By.XPATH,value=wait_element_xpath)))
        #     print_with_time(f"提示 : 检测到上传完毕的界面!")
        # except TimeoutException:
        #     print_with_time(f"提示 : 上传图片文件超时,请进行检测!")
        #     return
        wait_start_time = datetime.datetime.now()
        while wait_start_time + datetime.timedelta(seconds=30) > datetime.datetime.now():
            try:
                driver.find_element(by=By.XPATH,value=f"//*[contains(text(),'个文件上传成功')]")
                print_with_time(f"提示 : 写入上传操作成功,目前已经上完完毕!")
                element = driver.find_element(by=By.XPATH,value=f"//button/span[text()='完成']")
                try:
                    element.click()
                except  (ElementClickInterceptedException,ElementNotInteractableException):
                    driver.execute_script("arguments[0].click();",element)
                time.sleep(Delay)
                break
            except NoSuchElementException:
                time.sleep(Delay)

    except TimeoutException:
        print_with_time(f"提示 : 没有找到 {element_xpath} 的元素,无法进行上传图片!")
        return

    # 5.在上传完毕之后,要选择上传的图片
        # 获取所有上传图片的列表
    PictureList = PictureStr.split("\n")
    for index,picture_name in enumerate(PictureList,start=1):
        basename = pathlib.Path(picture_name).absolute().resolve().stem
        suffix = pathlib.Path(picture_name).absolute().resolve().suffix
        ImageSpaceName =  f"{basename}.jpg"
        
        try:
             element = WebDriverWait(driver=driver,timeout=10).until(expected_conditions.presence_of_element_located((By.XPATH,f"//div[contains(@class,'PicList_PicturesShow_main-show') and position() <= {PictureList.__len__()} and .//*[contains(text(),'{basename}')]]//img")))
             driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'});",element)      
             try:
                 element.click()
                 print_with_time(f"提示  : 点击图片 {ImageSpaceName} 成功!")
             except  (ElementClickInterceptedException,ElementNotInteractableException):
                  driver.execute_script("arguments[0].click();",element)
                  print_with_time(f"提示 : 点击图片 {ImageSpaceName} 失败!采用 js脚本点击!")
                  
        except TimeoutException:
            print_with_time(f"提示 : 没有找到第 {index} 张图片,该图片的文件名为 {ImageSpaceName}")
        finally:
            time.sleep(Delay)
            try:
                driver.find_element(by=By.XPATH,value=f"//span[text()='智能裁剪中']")
                time.sleep(Delay)
            except NoSuchElementException:
                pass

    driver.switch_to.default_content()
    time.sleep(Delay)




def On_InputPage_UploadMain_3b4_Picture_ByPictureNameList(driver:WebDriver,picture_name_list:list,Delay:float=5):
    """批量上传详情页图片.

    Args:
        driver (WebDriver): WebDriver 实例
        wait (WebDriverWait):  WebDriverWait 实例
        actions (ActionChains):  ActionChains 实例
        picture_name_list (list): 图片名称列表,可以是绝对路径,也可以是相对路径
        Delay (float, optional): 延迟时间. Defaults to 5.
    """
    
    # 1.将图片列表转换为 Selenium 可以使用的格式
    picture_list_str = ""
    for index, picture_name in enumerate(picture_name_list):
        picture_path = str(pathlib.Path(picture_name).absolute().resolve())
        if index >= 5 : continue
        if index > 0:  # 不是第一个元素时才添加换行符
            picture_list_str += "\n"
        picture_list_str += picture_path

    # 2.调用复用接口进行上传主图3:4图片
    On_InputPage_UploadMain_3b4_Picture_ByPictureNameStr(driver= driver,PictureStr=picture_list_str,Delay=Delay)



def On_InputPage_UploadMain_3b4_Picture_ByDirectory(driver:WebDriver,picture_directory_path:str,Delay:float=5):
    """批量上传  3:4 主图图片

    Args:
        driver (WebDriver): WebDriver 实例
        wait (WebDriverWait):  WebDriverWait 实例
        actions (ActionChains): ActionChains 实例
        picture_directory_path (str): 主图图片目录
        Delay (float, optional): 延时. Defaults to 5.
    """
    # 1.获取图片列表
    picture_name_list = list()
    for item in pathlib.Path(picture_directory_path).rglob('*'):
        if item.is_file():
            picture_image_path = str(item)
            picture_name_list.append(picture_image_path)
    
    # 2.将图片列表转换为 Selenium 可以使用的格式
    picture_list_str = ""
    for index, picture_name in enumerate(picture_name_list):
        picture_path = str(pathlib.Path(picture_name).absolute().resolve())
        if index >= 5 : continue
        if index > 0:  # 不是第一个元素时才添加换行符
            picture_list_str += "\n"
        picture_list_str += picture_path

    # 2.调用复用接口进行上传主图3:4图片
    On_InputPage_UploadMain_3b4_Picture_ByPictureNameStr(driver= driver,PictureStr=picture_list_str,Delay=Delay)